/*
 * CCamera.cpp
 *
 *  Created on: Sep 19, 2011
 *      Author: welcome
 */

#include "CCamera.h"

namespace GGEngine {

CCamera::CCamera() :
		m_center_x(0.0f), m_center_y(0.0f), m_center_z(0.0f), m_up_x(0.0f), m_up_y(
				1.0f), m_up_z(0.0f) {

}

CCamera::~CCamera() {

}
void CCamera::setEyePosition(GLfloat x, GLfloat y, GLfloat z) {
	m_x = x;
	m_y = y;
	m_z = z;
}
void CCamera::setCenter(GLfloat center_x, GLfloat center_y, GLfloat center_z) {
	m_center_x = center_x;
	m_center_y = center_y;
	m_center_z = center_z;
}

void CCamera::identity(GLfloat m[]) {
	kdMemset(m, 0, sizeof m[0] * 16);
	m[0] = m[5] = m[10] = m[15] = 1.0f;
}

void CCamera::normalize(float v[3]) {
	float r;
	r = (float) sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);

	if (r == 0.0)
		return;

	r = 1.f / r;

	v[0] *= r;
	v[1] *= r;
	v[2] *= r;
}

void CCamera::setUp(GLfloat up_x, GLfloat up_y, GLfloat up_z) {
	m_up_x = up_x;
	m_up_y = up_y;
	m_up_z = up_z;
}

void CCamera::crossProduct(float v0[3], float v1[3], float r[3]) {
	r[0] = v0[1] * v1[2] - v0[2] * v1[1];
	r[1] = v0[2] * v1[0] - v0[0] * v1[2];
	r[2] = v0[0] * v1[1] - v0[1] * v1[0];
}
void CCamera::lookAt() {

	GLfloat forward[3], side[3], up[3];

	GLfloat m[4][4];

	forward[0] = m_center_x - m_x;
	forward[1] = m_center_y - m_y;
	forward[2] = m_center_z - m_z;

	normalize(forward);

	up[0] = m_up_x;
	up[1] = m_up_y;
	up[2] = m_up_z;

	crossProduct(forward, up, side);

	normalize(side);

	crossProduct(side, forward, up);

	identity(&m[0][0]);

	m[0][0] = side[0];
	m[1][0] = side[1];
	m[2][0] = side[2];

	m[0][1] = up[0];
	m[1][1] = up[1];
	m[2][1] = up[2];

	m[0][2] = -forward[0];
	m[1][2] = -forward[1];
	m[2][2] = -forward[2];

	glMultMatrixf(&m[0][0]);

	glTranslatef(-m_x, -m_y, -m_z);
}
}
